<?php
namespace app\api\controller;

use think\facade\Log;
use think\Antiaddiction;

class Free
{
    private $appId;
    private $secretKey;
    private $bizId;
    private $apiBaseUrl = 'https://api.wlc.nppa.gov.cn';

    /**
     * 构造函数
     * @param string $appId 应用ID
     * @param string $secretKey 密钥
     * @param string $bizId 业务标识号
     */
    public function __construct()
    {
        $this->appId = "a9b6d5fe7e954c42a6f90226489e2bf7";
        $this->secretKey = "158bc88425a39f581d5140fc70e2fa79";
        $this->bizId = "1101999999";
    }

    /**
     * 实名认证接口
     * @param string $ai 游戏内部账号ID
     * @param string $name 真实姓名
     * @param string $idNum 身份证号码
     * @return array 认证结果
     */
    public function realNameAuth( $name, $idNum)
    {
        $url = $this->apiBaseUrl . '/idcard/authentication/check';
        $data = [
            'ai' => md5($this->appId .$idNum),
            'name' => $name,
            'idNum' => $idNum
        ];

        return $this->sendRequest($url, 'POST', $data);
    }

    /**
     * 实名查询接口
     * @param string $ai 游戏内部账号ID
     * @return array 查询结果
     */
    public function queryRealNameInfo()
    {
        $url = $this->apiBaseUrl . '/idcard/authentication/query';
        $params = [
            'bizId' => $this->bizId, // 添加bizId参数
            'ai' => md5($this->appId .$idNum),
        ];

        return $this->sendRequest($url, 'GET', $params);
    }

    /**
     * 行为数据上报接口
     * @param string $ai 游戏内部账号ID
     * @param int $behaviorType 行为类型(1:登录, 2:登出)
     * @param int $onlineTime 在线时长(秒)
     * @return array 上报结果
     */
    public function reportBehavior($behaviorType, $onlineTime = 0)
    {
        $url = $this->apiBaseUrl . '/behavior/collection/loginout';
        $data = [
            'collections'=>[
                [
                    'no'=>1,
                    'si'=> md5($this->appId . $pi),//一个会话标识只能对应唯一的实名用户，一个实名用户可以拥有多个会话标识；同一用户单次游戏会话中，上下线动作必须使用同一会话标识上报备注：会话标识仅标识一次用户会话，生命周期仅为一次上线和与之匹配的一次下线，不会对生命周期之外的任何业务有任何影响
                    'bt'=>0,  ///游戏用户行为类型 0：下线 1：上线
                    'ot'=>time(),
                    'ct'=>2,  ///用户行为数据上报类型 0：已认证通过用户 2：游客用户
                    'di'=>'ecvndx6r6xfwofmufs3lbimcr639r33t',
                    'pi'=>$pi,
                ]
            ],
        ];
        return $this->sendRequest($url, 'POST', $data);
    }
    /**
     * 加密请求体
     * @param $text
     * @return string
     */
    protected function encrypt($text)
    {
        $key = hex2bin($this->secret_key);
        $cipher = "aes-128-gcm";

        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));

        //php7.1以上可直接使用以下代码
        if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
            $encrypt = openssl_encrypt($text, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
            return base64_encode($iv . $encrypt . $tag);
        }

        //php5.6-7.0使用以下代码
        list($encrypt, $tag) = AESGCM::encrypt($key, $iv, $text);
        $str = bin2hex($iv) . bin2hex($encrypt) . bin2hex($tag);
        return base64_encode(hex2bin($str));
    }

    /**
     * 发送HTTP请求
     * @param string $url 请求地址
     * @param string $method 请求方法(GET/POST)
     * @param array $data 请求数据
     * @return array 响应结果
     * @throws Exception
     */
    private function sendRequest($url, $method = 'GET', $data = [])
    {
        // 生成签名所需的参数
        $timestamp = (int)(microtime(true) * 1000);
        $signature = $this->generateSignature($timestamp);

        // 设置请求头
        $headers = [
            'Content-Type:application/json',
            'appId:' . $this->appId,
            'bizId:' . $this->bizId,  // 添加bizId到header
            'timestamps:' . $timestamp,
            'sign:' . $signature,      // 根据文档可能需要改为sign
        ];
        dump($headers);
        dump(json_encode($data));exit;
        // 初始化cURL
        $ch = curl_init();

        // 根据请求方法设置参数
        if (strtoupper($method) === 'GET' && !empty($data)) {
            $url .= '?' . http_build_query($data);
        } elseif (strtoupper($method) === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data,JSON_UNESCAPED_UNICODE));
        }

        // 设置cURL选项
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 10秒超时
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        // 执行请求
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        // 处理错误
        if ($response === false) {
            Log::info('实名认证返回数据：' . json_encode($error));
        }

        // 解析响应
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            Log::info('JSON解析失败：' . json_last_error_msg());
        }

        // 记录日志(实际项目中应该使用日志系统)
        $this->logRequest($url, $method, $data, $httpCode, $result);

        return $result;
    }

    /**
     * 生成签名
     * @param int $timestamp 时间戳
     * @param string $nonce 随机字符串
     * @return string 签名
     */
    private function generateSignature($timestamp)
    {
        $stringToSign = $this->secretKey."appId{$this->appId}bizId{$this->bizId}timestamps{$timestamp}";

        return strtolower(hash('sha256', $stringToSign));
    }

    /**
     * 记录请求日志(示例)
     * @param string $url 请求URL
     * @param string $method 请求方法
     * @param array $requestData 请求数据
     * @param int $httpCode HTTP状态码
     * @param array $response 响应数据
     */
    private function logRequest($url, $method, $requestData, $httpCode, $response)
    {
        // 实际项目中应该使用日志系统如Monolog
        $logData = [
            'date' => date('Y-m-d H:i:s'),
            'url' => $url,
            'method' => $method,
            'request' => $requestData,
            'http_code' => $httpCode,
            'response' => $response
        ];

        // 示例：写入文件(生产环境建议使用专业日志系统)
        file_put_contents(
            __DIR__ . '/nppa_api.log',
            json_encode($logData, JSON_UNESCAPED_UNICODE) . PHP_EOL,
            FILE_APPEND
        );
    }

}
